package cn.picclife.mwx.manager.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class ZipUtil {
    private static final Log log = LogFactory.getLog(ZipUtil.class);

	/** 
     * 删除单个文件 
     * @param   sPath    被删除文件的文件名 
     * @return 单个文件删除成功返回true，否则返回false 
     */  
    public static boolean deleteFile(String sPath) {  
        boolean flag = false;  
        File file = new File(sPath);  
        // 路径为文件且不为空则进行删除  
        if (file.isFile() && file.exists()) {  
            file.delete();  
            flag = true;  
        }  
        return flag;  
    }
    
	/**
     * zip文件压缩
     * @param inputFile 待压缩文件夹/文件名
     * @param outputFile 生成的压缩包名字
     */

    public static void ZipCompress(String inputFile, String outputFile) throws Exception {
    	 File zipFile = new File(outputFile);	 
        //创建zip输出流
    	 ZipOutputStream  out = new ZipOutputStream(new FileOutputStream(outputFile));
        //创建缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(out);
        File input = new File(inputFile);
        compress(out, bos, input,null);
        bos.close();
        out.close();
    }
    /**
     * @param name 压缩文件名，可以写为null保持默认
     */
    //递归压缩
    public static void compress(ZipOutputStream out, BufferedOutputStream bos, File input, String name) throws IOException {
        if (name == null) {
            name = input.getName();
        }
        //如果路径为目录（文件夹）
        if (input.isDirectory()) {
            //取出文件夹中的文件（或子文件夹）
            File[] flist = input.listFiles();

            if (flist.length == 0)//如果文件夹为空，则只需在目的地zip文件中写入一个目录进入
            {
                out.putNextEntry(new ZipEntry(name + "/"));
            } else//如果文件夹不为空，则递归调用compress，文件夹中的每一个文件（或文件夹）进行压缩
            {
                for (int i = 0; i < flist.length; i++) {
                    compress(out, bos, flist[i], name + "/" + flist[i].getName());
                }
            }
        } else//如果不是目录（文件夹），即为文件，则先写入目录进入点，之后将文件写入zip文件中
        {
            out.putNextEntry(new ZipEntry(name));
            FileInputStream fos = new FileInputStream(input);
            BufferedInputStream bis = new BufferedInputStream(fos);
            int len=-1;
            //将源文件写入到zip文件中
            byte[] buf = new byte[1024];
            while ((len = bis.read(buf)) != -1) {
                bos.write(buf,0,len);
                bos.flush();
            }
            bis.close();
            fos.close();
            
        }
    }
    
    
//    public static void main(String[] args) {
//        try {
//            zipUncompress("D:\\ytt.zip","D:\\ytt的解压文件");
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
    /**
     * zip文件解压
     * @param inputFile  待解压文件夹/文件
     * @param destDirPath  解压路径
     */
    public static void zipUncompress(String inputFile,String destDirPath) throws Exception {
        File srcFile = new File(inputFile);//获取当前压缩文件
        // 判断源文件是否存在
        if (!srcFile.exists()) {
            throw new Exception(srcFile.getPath() + "所指文件不存在");
        }
        ZipFile zipFile = new ZipFile(srcFile);//创建压缩文件对象
        //开始解压
        Enumeration<?> entries = zipFile.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = (ZipEntry) entries.nextElement();
            // 如果是文件夹，就创建个文件夹
            if (entry.isDirectory()) {
                String dirPath = destDirPath + "/" + entry.getName();
                srcFile.mkdirs();
            } else {
                // 如果是文件，就先创建一个文件，然后用io流把内容copy过去
                File targetFile = new File(destDirPath + "/" + entry.getName());
                // 保证这个文件的父文件夹必须要存在
                if (!targetFile.getParentFile().exists()) {
                    targetFile.getParentFile().mkdirs();
                }
                targetFile.createNewFile();
                // 将压缩文件内容写入到这个文件中
                InputStream is =null;
                FileOutputStream fos=null;
                try{
                    is = zipFile.getInputStream(entry);
                    fos = new FileOutputStream(targetFile);
                    int len;
                    byte[] buf = new byte[1024];
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }}catch(Exception e){
                        log.error(e);
                }finally {
                    // 关流顺序，先打开的后关闭
                    try {
                        if(fos!=null){
                            fos.close();
                        }
                    }catch (Exception e){
                        log.error(e);
                    }
                    try {
                        if(is!=null){
                            is.close();
                        }
                    }catch (Exception e){
                        log.error(e);
                    }
                }

            }
        }
    }
    
    /**
	 * 解压压缩文件
	 * @param outPath 解压路径
	 * @param unzipfile 解压的文件路径
	 * @return
	 * @throws IOException
	 */
	public static Boolean unZip(String outPath, String unzipfile) throws IOException {
		//String unzipfile = "D:\\test\\15000044#20150126144822.DAT.zip"; // 解压缩的文件名
		try {
			File file = new File(unzipfile);
			ZipInputStream zipInput = new ZipInputStream(new FileInputStream(file));
			ZipEntry entry = null;

			while ((entry = zipInput.getNextEntry()) != null) {
				if (entry.isDirectory()) {
                    try{
                        File directory = new File(outPath, entry.getName());
                        if (!directory.exists()) {
                            if (!directory.mkdirs()) {
                                return false;
                            }
                        }
                    }catch(Exception e){
                        log.error(e);
                    }finally {
                        try {
                            if(zipInput!=null){
                                zipInput.closeEntry();
                            }
                        }catch (Exception e){
                            log.error(e);
                        }
                    }
				} else {
					File myFile = new File(entry.getName());
					FileOutputStream fout = new FileOutputStream(outPath+"/"
							+ myFile.getPath());
					DataOutputStream dout = new DataOutputStream(fout);
					try{
                        byte[] b = new byte[1024];
                        int len = 0;
                        while ((len = zipInput.read(b)) != -1) {
                            dout.write(b, 0, len);
                        }
                    }catch(Exception e){
					    log.error(e);
                    }finally {
					    try{
					        if(dout!=null){dout.close();}
					    }catch (Exception e){log.error(e);}
					    try{
					        if(fout!=null){fout.close();}
                        }catch (Exception e){log.error(e);}
					    try{
					        if(zipInput!=null){zipInput.closeEntry();}
                        }catch (Exception e){log.error(e);}

                    }

				}
			}
			return true;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}

	}
    
}
